import json
import time
import logging
import asyncio
import os
import traceback
from typing import Dict, Any, List, Optional, Callable
import random

class IoTHandler:
    """IoT设备能力处理器，负责IoT设备能力的注册、命令处理和响应"""

    def __init__(self, send_json_callback: Callable):
        """初始化IoT处理器

        Args:
            send_json_callback: 发送JSON消息的回调函数
        """
        self.logger = logging.getLogger("xiaozhi")
        self.send_json_callback = send_json_callback
        self.registered_callbacks = {}  # 存储已注册的回调函数

        # 设备状态存储
        self.device_states = {}

        # 从文件加载IoT设备描述符
        self.iot_descriptors = self._load_iot_descriptors()

        # 状态上报相关
        self.status_report_task = None
        self.report_interval = 5  # 默认5秒上报一次
        self.should_stop_reporting = False

        # 添加client引用，用于状态上报
        self.client = None

        self.enable_iot_report = True  # 默认开启IoT上报

    def set_client(self, client):
        """设置客户端引用，便于状态上报

        Args:
            client: 客户端对象
        """
        self.client = client
        self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已设置IoT客户端引用")

    def _load_iot_descriptors(self) -> List[Dict[str, Any]]:
        """从iot.json加载设备描述符

        Returns:
            List[Dict[str, Any]]: 设备描述符列表
        """
        try:
            # 获取iot.json的路径
            iot_json_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "iot.json")
            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 加载IoT设备描述符文件: {iot_json_path}")

            if not os.path.exists(iot_json_path):
                self.logger.error(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] IoT设备描述符文件不存在: {iot_json_path}")
                return []

            # 读取iot.json文件
            with open(iot_json_path, "r", encoding="utf-8") as f:
                iot_data = json.load(f)

            # 提取描述符
            descriptors = iot_data.get("descriptors", [])
            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 成功加载 {len(descriptors)} 个IoT设备描述符")

            # 日志记录每个设备
            for descriptor in descriptors:
                device_name = descriptor.get("name")
                device_desc = descriptor.get("description")
                methods_count = len(descriptor.get("methods", {}))
                self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] - 设备: {device_name} ({device_desc}), {methods_count}个方法")

                # 初始化设备状态
                self._init_device_state(device_name, descriptor)

            return descriptors
        except Exception as e:
            self.logger.error(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 加载IoT设备描述符文件失败: {str(e)}")
            return []

    def _init_device_state(self, device_name: str, descriptor: Dict[str, Any]):
        """初始化设备状态

        Args:
            device_name: 设备名称
            descriptor: 设备描述符
        """
        properties = descriptor.get("properties", {})
        state = {}

        # 根据属性定义动态初始化状态
        for prop_name, prop_info in properties.items():
            prop_type = prop_info.get("type", "string")
            
            # 根据不同属性类型设置默认值
            if prop_type == "number":
                # 有些特殊处理的默认值
                if device_name == "AL" and prop_name == "sw":
                    state[prop_name] = 1  # 氛围灯开关默认为开
                elif device_name == "AL" and prop_name == "set_type":
                    state[prop_name] = 2  # 氛围灯设置模式默认为2
                elif device_name == "AL" and prop_name == "brightness":
                    state[prop_name] = 50  # 氛围灯亮度默认50
                elif device_name == "AL" and (prop_name in ["color_r", "color_g", "color_b"]):
                    state[prop_name] = 255  # 氛围灯RGB颜色默认255
                elif device_name == "AC" and prop_name == "temp":
                    state[prop_name] = 25  # 空调温度默认25度
                elif device_name == "VOL" and (prop_name in ["inner_vol", "brightness", "color_r"]):
                    state[prop_name] = 50  # 音量默认50
                elif prop_name == "pl" or prop_name == "rem_time":
                    state[prop_name] = -1  # 剩余电量/时间默认-1表示未知
                else:
                    state[prop_name] = 0  # 其他数字类型默认为0
            
            elif prop_type == "boolean":
                # 特殊处理的布尔值
                if device_name == "V" and prop_name == "sw":
                    state[prop_name] = False  # 车门默认关闭
                elif device_name == "V" and prop_name == "located":
                    state[prop_name] = False  # 定位默认关闭
                else:
                    state[prop_name] = False  # 其他布尔类型默认为False
            
            elif prop_type == "string":
                # 特殊处理的字符串值
                if device_name == "V" and prop_name == "g":
                    state[prop_name] = "P"  # 车辆挡位默认为P
                elif device_name == "V" and (prop_name in ["lng", "lat", "rem_dist", "spd"]):
                    state[prop_name] = "0"  # 经纬度、距离、速度默认为"0"
                elif device_name == "V" and (prop_name in ["next_stop", "current_stop"]):
                    state[prop_name] = ""   # 站点名称默认为空
                else:
                    state[prop_name] = ""  # 其他字符串类型默认为空字符串

        # 存储设备状态
        self.device_states[device_name] = state
        self.logger.debug(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 初始化设备 {device_name} 状态: {json.dumps(state, ensure_ascii=False)}")

    async def register_capabilities(self):
        """注册IoT设备能力"""
        try:
            # 只在成功加载了设备描述符的情况下进行注册
            if self.iot_descriptors:
                self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 使用从iot.json加载的设备描述符进行注册")

                # 发送注册请求
                message = {
                    "type": "iot",
                    "action": "descriptor",
                    "descriptors": self.iot_descriptors
                }

                self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 发送IoT设备描述符注册消息")
                self.logger.debug(f"IoT设备描述符: {json.dumps(self.iot_descriptors, ensure_ascii=False, indent=2)}")
                await self.send_json_callback(message)
                self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已发送IoT设备描述符注册请求")
            else:
                self.logger.warning(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 未能从iot.json加载设备描述符，跳过IoT设备注册")
        except Exception as e:
            self.logger.error(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 注册IoT设备能力时出错: {str(e)}")

    async def handle_message(self, message: Dict[str, Any]):
        """处理IoT消息

        Args:
            message: IoT消息
        """
        action = message.get("action")
        commands = message.get("commands", [])

        if action == "descriptor_response":
            # 处理IoT设备描述符注册响应
            await self._handle_register_response(message)
        elif commands and len(commands) > 0:
            # 处理IoT命令
            for command in commands:
                await self._handle_command(command)
        else:
            self.logger.warning(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 未知的IoT消息: {message}")

    async def _handle_register_response(self, message: Dict[str, Any]):
        """处理IoT设备能力注册响应

        Args:
            message: 注册响应消息
        """
        try:
            status = message.get("status", "unknown")
            registered_descriptors = message.get("registered_descriptors", [])
            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 收到IoT设备描述符注册响应:")
            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] - 状态: {status}")
            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] - 已注册的设备描述符: {registered_descriptors}")

            if status == "success":
                self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 成功注册IoT设备描述符")
                # 更新已注册的设备列表和方法映射
                self.registered_callbacks = {}
                for descriptor in registered_descriptors:
                    device_name = descriptor.get("name")
                    for method_name in descriptor.get("methods", {}).keys():
                        callback_name = f"{device_name}.{method_name}"
                        self.registered_callbacks[callback_name] = {
                            "name": callback_name,
                            "device_name": device_name,
                            "method_name": method_name
                        }
                        self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] - 已添加到注册列表: {callback_name}")
            else:
                error_msg = message.get("message", "未知错误")
                self.logger.error(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 注册IoT设备描述符失败: {error_msg}")
        except Exception as e:
            self.logger.error(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 处理IoT设备描述符注册响应时出错: {str(e)}")

    async def _handle_command(self, command: Dict[str, Any]):
        """处理IoT命令

        Args:
            command: 命令消息
        """
        try:
            device_name = command.get("name")
            method_name = command.get("method")
            parameters = command.get("parameters", {})

            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 收到IoT命令: {device_name}.{method_name}")
            self.logger.debug(f"命令参数: {parameters}")

            # 根据设备和方法执行命令
            success = self._execute_device_command(device_name, method_name, parameters)

            # 获取设备当前状态
            state = self._get_device_state(device_name, parameters)

            # 发送状态响应
            response = {
                "type": "iot",
                "states": [
                    {
                        "name": device_name,
                        "state": state
                    }
                ]
            }

            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 发送IoT状态响应: {json.dumps(response, ensure_ascii=False)}")
            await self.send_json_callback(response)

        except Exception as e:
            # 处理命令执行错误
            error_msg = f"执行命令出错: {str(e)}"
            self.logger.error(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 命令执行失败: {error_msg}")

            # 尝试发送错误响应
            try:
                response = {
                    "type": "iot",
                    "states": [
                        {
                            "name": device_name,
                            "state": self._get_device_state(device_name, {}),
                            "error": error_msg
                        }
                    ]
                }

                self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 发送IoT错误状态响应")
                await self.send_json_callback(response)
            except Exception as send_error:
                self.logger.error(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 发送错误响应失败: {str(send_error)}")

    def _execute_device_command(self, device_name: str, method_name: str, parameters: Dict[str, Any]) -> bool:
        """执行设备命令并更新状态

        Args:
            device_name: 设备名称
            method_name: 方法名称
            parameters: 命令参数

        Returns:
            bool: 是否执行成功
        """
        # 检查设备是否存在
        device_found = False
        for descriptor in self.iot_descriptors:
            if descriptor.get("name") == device_name:
                device_found = True
                methods = descriptor.get("methods", {})
                if method_name in methods:
                    # 更新设备状态
                    if device_name == "AI" and method_name == "ai_stop_a_talk":
                        # AI停止对话，无需更新状态
                        self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 执行AI停止对话命令")
                        return True
                    elif device_name == "AL" and method_name == "al_set_l_rgb":
                        # 氛围灯设置命令
                        set_type = parameters.get("set_type", 0)
                        brightness = parameters.get("brightness", 50)
                        color_r = parameters.get("color_r", 255)
                        color_g = parameters.get("color_g", 255)
                        color_b = parameters.get("color_b", 255)

                        # 更新状态
                        if device_name not in self.device_states:
                            self.device_states[device_name] = {}

                        self.device_states[device_name].update({
                            "set_type": set_type,
                            "brightness": brightness,
                            "color_r": color_r,
                            "color_g": color_g,
                            "color_b": color_b,
                            "sw": 1 if brightness > 0 else 0
                        })

                        self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已设置氛围灯: 类型={set_type}, 亮度={brightness}, 颜色=({color_r},{color_g},{color_b})")
                        return True
                    elif device_name == "V" and method_name == "v_set_door":
                        # 车门设置命令
                        sw = parameters.get("sw", False)

                        # 更新状态
                        if device_name not in self.device_states:
                            self.device_states[device_name] = {}

                        self.device_states[device_name].update({
                            "sw": sw
                        })

                        self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已设置车门状态: {'开门' if sw else '关门'}")
                        return True
                    elif device_name == "AC" and method_name == "ac_set":
                        # 空调设置命令
                        auto_mode = parameters.get("auto_mode", -1)
                        mode = parameters.get("mode", -1)
                        circulation_mode = parameters.get("circulation_mode", -1)
                        gear = parameters.get("gear", -1)
                        temp = parameters.get("temp", -1)
                        defrost_sw = parameters.get("defrost_sw", -1)

                        # 更新状态（仅更新非-1的值）
                        if device_name not in self.device_states:
                            self.device_states[device_name] = {}

                        state_updates = {}
                        if auto_mode != -1:
                            state_updates["auto_mode"] = auto_mode
                        if mode != -1:
                            state_updates["mode"] = mode
                        if circulation_mode != -1:
                            state_updates["circulation_mode"] = circulation_mode
                        if gear != -1:
                            state_updates["gear"] = gear
                        if temp != -1:
                            state_updates["temp"] = temp
                        if defrost_sw != -1:
                            state_updates["defrost_sw"] = defrost_sw

                        self.device_states[device_name].update(state_updates)

                        self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已设置空调参数: {state_updates}")
                        return True
                    elif device_name == "VOL":
                        if method_name == "vol_set_inner":
                            # 设置车内音量
                            vol = parameters.get("vol", 50)
                            if device_name not in self.device_states:
                                self.device_states[device_name] = {}
                            self.device_states[device_name]["inner_vol"] = vol
                            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已设置车内音量: {vol}")
                            return True
                        elif method_name == "vol_set_out":
                            # 设置车外音量
                            vol = parameters.get("vol", 50)
                            if device_name not in self.device_states:
                                self.device_states[device_name] = {}
                            self.device_states[device_name]["brightness"] = vol
                            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已设置车外音量: {vol}")
                            return True
                        elif method_name == "vol_set_side":
                            # 设置侧屏音量
                            vol = parameters.get("vol", 50)
                            if device_name not in self.device_states:
                                self.device_states[device_name] = {}
                            self.device_states[device_name]["color_r"] = vol
                            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 已设置侧屏音量: {vol}")
                            return True

                    # 其他未特殊处理的方法，记录日志
                    self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 执行命令: {device_name}.{method_name}，但未实现具体逻辑")
                    return True
                else:
                    error_msg = f"设备 {device_name} 不支持方法 {method_name}"
                    self.logger.warning(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] {error_msg}")
                    raise ValueError(error_msg)

        if not device_found:
            error_msg = f"未知设备: {device_name}"
            self.logger.warning(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] {error_msg}")
            raise ValueError(error_msg)

        return False

    def _get_device_state(self, device_name: str, parameters: Dict[str, Any]) -> Dict[str, Any]:
        """获取设备当前状态

        Args:
            device_name: 设备名称
            parameters: 命令参数（可用于临时状态构建）

        Returns:
            Dict[str, Any]: 设备状态
        """
        # 返回已存储的设备状态
        if device_name in self.device_states:
            return self.device_states[device_name]

        # 如果没有存储状态，则返回空状态
        return {}

    def get_capabilities(self) -> Dict[str, Any]:
        """获取设备能力定义

        Returns:
            Dict[str, Any]: 设备能力定义
        """
        # 从iot.json加载的设备描述符构建能力定义
        if self.iot_descriptors:
            capabilities = {}
            for descriptor in self.iot_descriptors:
                device_name = descriptor.get("name")
                device_desc = descriptor.get("description", "")
                methods = descriptor.get("methods", {})

                # 构建命令字典
                commands = {}
                for method_name, method_info in methods.items():
                    commands[method_name] = {
                        "name": method_name,
                        "description": method_info.get("description", ""),
                        "parameters": {
                            "type": "object",
                            "properties": method_info.get("parameters", {}),
                            "required": [param for param, info in method_info.get("parameters", {}).items()
                                         if info.get("required", False)]
                        }
                    }

                # 添加到能力定义
                capabilities[device_name] = {
                    "name": device_desc,
                    "commands": commands
                }

            self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 从iot.json生成了 {len(capabilities)} 个设备能力定义")
            return capabilities

        # 如果没有加载成功，则返回空字典
        self.logger.warning(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 未能加载设备能力定义")
        return {}

    async def start_status_reporting(self, report_interval=None):
        """启动设备状态上报任务

        Args:
            report_interval (float, optional): 状态上报间隔，单位秒。
                                              如果未指定，将尝试从iot.json中获取，
                                              若未配置则默认为5秒。
        """
        if self.status_report_task and not self.status_report_task.done():
            self.logger.info("状态上报任务已在运行中")
            return

        # 尝试从iot.json中获取上报间隔设置
        if report_interval is None:
            try:
                report_interval = self.config.get("status_report_interval", 5)
                self.logger.info(f"从配置中获取状态上报间隔: {report_interval}秒")
            except (AttributeError, KeyError):
                report_interval = 5
                self.logger.info(f"使用默认状态上报间隔: {report_interval}秒")

        self.report_interval = report_interval
        self.logger.info(f"启动IoT设备状态上报任务，间隔: {self.report_interval}秒")
        self.status_report_task = asyncio.create_task(self._status_report_loop())
        # 立即上报一次状态
        await self._report_all_device_status()

    async def stop_status_reporting(self):
        """停止设备状态上报任务"""
        if self.status_report_task:
            self.logger.info("正在停止设备状态上报任务...")
            self.should_stop_reporting = True

            # 等待任务完成
            try:
                await asyncio.wait_for(self.status_report_task, timeout=2.0)
            except asyncio.TimeoutError:
                # 如果超时，则尝试取消任务
                self.logger.warning("停止设备状态上报任务超时，强制取消")
                self.status_report_task.cancel()
                try:
                    await self.status_report_task
                except asyncio.CancelledError:
                    pass

            self.status_report_task = None
            self.logger.info("设备状态上报任务已停止")

    async def _status_report_loop(self):
        """设备状态定时上报循环"""
        self.should_stop_reporting = False

        try:
            while not self.should_stop_reporting:
                try:
                    await self._report_all_device_status()
                except Exception as e:
                    self.logger.error(f"上报设备状态时发生错误: {e}")

                try:
                    # 使用可中断的等待，便于快速响应退出请求
                    for _ in range(int(self.report_interval * 2)):
                        if self.should_stop_reporting:
                            break
                        await asyncio.sleep(0.5)
                except asyncio.CancelledError:
                    self.should_stop_reporting = True
                    break
        except Exception as e:
            self.logger.error(f"状态上报循环发生异常: {e}")
        finally:
            self.logger.info("设备状态上报任务已停止")

    async def get_device_status(self, device_type: str, device_id: str) -> Dict[str, Any]:
        """获取设备状态，用于状态上报

        Args:
            device_type: 设备类型
            device_id: 设备ID

        Returns:
            Dict[str, Any]: 设备状态
        """
        # 如果设备类型存在于device_states中，返回对应状态
        if device_type in self.device_states:
            return self.device_states[device_type]
        else:
            self.logger.debug(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 未找到设备类型 {device_type} 的状态")
            return {}

    async def _report_all_device_status(self):
        """上报所有设备状态"""
        try:
            if not getattr(self, 'enable_iot_report', True):
                self.logger.info("[IoT] 配置禁用IoT状态上报，跳过上报流程")
                return
            states = []
            
            # 更新设备状态，为非枚举字段生成随机值
            self._update_device_states_with_random_values()
            
            # 将设备状态转换为服务端期望的格式
            for device_name, state in self.device_states.items():
                if state:  # 只上报有状态的设备
                    states.append({
                        "name": device_name,
                        "state": state
                    })
            
            # 如果有状态数据，则上报
            if states:
                self.logger.info(f"上报设备状态: {json.dumps(states, ensure_ascii=False)}")
                
                # 优先使用client.websocket发送
                if self.client and hasattr(self.client, 'websocket') and self.client.websocket and not self.client.websocket.closed:
                    await self.client.websocket.send(json.dumps({
                        "type": "iot",
                        "states": states
                    }))
                # 如果client.websocket不可用，使用callback函数
                elif self.send_json_callback:
                    await self.send_json_callback({
                        "type": "iot",
                        "states": states
                    })
                else:
                    self.logger.warning("WebSocket未连接，无法上报设备状态")
        except Exception as e:
            self.logger.error(f"上报设备状态时发生错误: {str(e)}")
            self.logger.error(traceback.format_exc())
            
    def _update_device_states_with_random_values(self):
        """更新设备状态，为非枚举字段生成随机值"""
        # 预定义的车站名称列表，用于随机选择
        station_names = [
            "中关村", "望京", "天安门", "西单", "国贸", "五道口", "回龙观",
            "海淀黄庄", "立水桥", "北京南站", "三元桥", "亦庄", "石景山", "大兴机场"
        ]
        
        # 北京市中心的经纬度范围(近似)
        beijing_lat_range = (39.8, 40.2)  # 纬度范围
        beijing_lng_range = (116.2, 116.6)  # 经度范围
        
        # 处理车辆(V)相关的随机数据
        if "V" in self.device_states:
            v_state = self.device_states["V"]
            
            # 随机切换定位状态，10%的概率改变定位状态
            if random.random() < 0.1:
                v_state["located"] = not v_state.get("located", False)
                self.logger.info(f"[{time.strftime('%H:%M:%S')}.{int(time.time()*1000)%1000:03d}] 车辆定位状态已切换为: {'开启' if v_state['located'] else '关闭'}")
            
            # 车辆位置信息 - 无论是否定位，都更新经纬度，保证数据的变化
            v_state["lng"] = str(round(random.uniform(beijing_lng_range[0], beijing_lng_range[1]), 6))  # 经度，保留6位小数
            v_state["lat"] = str(round(random.uniform(beijing_lat_range[0], beijing_lat_range[1]), 6))  # 纬度，保留6位小数
            
            # 站点信息 - 无论定位状态如何都设置值
            v_state["current_stop"] = random.choice(station_names)
            v_state["next_stop"] = random.choice([s for s in station_names if s != v_state["current_stop"]])
            
            # 如果定位已开启，更新距离信息及其他数据
            if v_state.get("located", False):
                # 剩余距离，1-15公里范围内随机生成
                v_state["rem_dist"] = str(round(random.uniform(1.0, 15.0), 2))
                
                # 剩余时间，3-30分钟范围内随机生成
                v_state["rem_time"] = random.randint(3, 30)
                
                # 车速，0-80km/h范围内随机生成
                v_state["spd"] = str(random.randint(0, 80))
                
                # 剩余电量，40-400公里范围内随机生成
                v_state["pl"] = random.randint(40, 400)
            else:
                # 如果未定位，保持特定值表示无法获取
                v_state["rem_dist"] = "0"
                v_state["rem_time"] = -1
                v_state["spd"] = "0"
                v_state["pl"] = -1
            
            # 随机切换挡位，但保持一定概率不变
            if random.random() < 0.8:  # 80%的概率保持不变
                pass
            else:
                # 随机挡位：P(停车)、R(倒车)、N(空挡)、D(前进)
                v_state["g"] = random.choice(["P", "R", "N", "D"])